<?php

namespace App\Modules\Admin\Services\Water\Statistic;

use App\Modules\Admin\Entities\Member\UserScoreModel;
use App\Modules\Admin\Entities\Member\UsersWithApparatuses;
use App\Modules\Admin\Entities\Member\UserWaterIntakeLogModel;
use App\Modules\Admin\Entities\Water\ApparatusElectricityLogModel;
use App\Modules\Admin\Entities\Water\ApparatusPropertyFeeLogModel;
use App\Modules\Admin\Entities\Water\ApparatusPropertyFreeModel;
use App\Modules\Admin\Entities\Water\ApparatusWaterRateLogModel;
use App\Modules\Admin\Services\BaseService;
use \App\Modules\Admin\Services\Water\Apparatus\ApparatusService;
use Illuminate\Support\Arr;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

class StatisticService extends BaseService
{
    /**
     * @param $id
     * @param $startTime
     * @param $endTime
     * @param $type
     * @return array
     */
    public function getSelectListApparatus($request){

        $id=$request->input('id');
        $type=$request->input('type','month');
        $startTime=$request->input('start_time');
        $endTime=$request->input('end_time');
        [$date,$startDate,$endDate] = self::getDateList($type, $startTime, $endTime);
        /**
         * @var Carbon $startDate
         * @var Carbon $endDate
         */
        $waterRate = self::getEveryPriceToECharts($id,$date,$startDate->toDateString(), $endDate->toDateString(),
            $type,new ApparatusWaterRateLogModel());
        //电费
        $electricity = self::getEveryPriceToECharts($id,$date,$startDate->toDateString(), $endDate->toDateString(),
            $type,new ApparatusElectricityLogModel());
        //物业费
        $propertyFee = self::getEveryPriceToECharts($id,$date,$startDate->toDateString(), $endDate->toDateString(),
            $type,new ApparatusPropertyFeeLogModel());
        /******************  会员相关  *************************/
        [$groupBy,$time,$startDate,$endDate] = self::type2Orm($startTime,$endTime,$type);
        $userWaterIntakeLogOrm = UserWaterIntakeLogModel::whereBetween('created_time', [$startDate->timestamp, $endDate->timestamp])    // 月份结束时间
        ->select($time,DB::raw('COUNT(*) as count'))
            ->groupBy($groupBy)
            ->orderBy('time');

        //购买卡
        $buyQuery = clone $userWaterIntakeLogOrm;
        $buy = $buyQuery->whereIn('type', [0, 1])
            ->pluck('count','time');
        $buy = array_map(function($month) use ($buy) {
            return (int)$buy->get($month, 0); // 如果 $month 存在于 $ormResults 中，返回对应值；否则返回 0
        }, $date);

        //赠送卡
        $sendQuery = clone $userWaterIntakeLogOrm;
        $send = $sendQuery->where('type',2)
            ->pluck('count','time');

        $send = array_map(function($month) use ($send) {
            return (int)$send->get($month, 0); // 如果 $month 存在于 $ormResults 中，返回对应值；否则返回 0
        }, $date);
        return [
            'date' => $date,
            'series' => [
                [
                    'name' => '电费',
                    'data' => $electricity
                ],
                [
                    'name' => '水费',
                    'data' => $waterRate
                ],
                [
                    'name' => '物业费',
                    'data' => $propertyFee
                ],
                [
                    'name' => '赠送卡',
                    'data' => $send
                ],
                [
                    'name' => '购买卡',
                    'data' => $buy
                ]
            ]
        ];
    }

    public function getSelectListScores($request){

        $id=$request->input('id');
        $type=$request->input('type','month');
        $startTime=$request->input('start_time');
        $endTime=$request->input('end_time');
        return $this->getScores($startTime, $endTime, $type,$id);
    }

    /**
     * @param $id
     * @param $date
     * @param $startTime
     * @param $endTime
     * @param $type
     * @param \App\Modules\Apibackstage\Entities\Admin\ApparatusWaterRateLogModel|\App\Modules\Apibackstage\Entities\Admin\ApparatusPropertyFeeLogModel|\App\Modules\Apibackstage\Entities\Admin\ApparatusElectricityLogModel $orm
     * @return int[]
     */
    public function getEveryPriceToECharts($id, $date, $startTime, $endTime, $type, $orm): array
    {
        if ($type == 'year') {
            $groupBy = DB::raw('YEAR(date)');
            $time = DB::raw('YEAR(date) as time');
        }else{
            $groupBy = DB::raw('CONCAT(YEAR(date), "-", LPAD(MONTH(date), 2, "0"))');
            $time = DB::raw('CONCAT(YEAR(date), "-", LPAD(MONTH(date), 2, "0")) as time');
        }
        $data = $orm::where('apparatus_id', $id)
            ->whereBetween('date', [$startTime, $endTime])
            ->select(
                $time,
                DB::raw('SUM(price) as total_price')
            )
            ->groupBy($groupBy)
            ->orderBy('time')
            ->pluck('total_price','time');
        return array_map(function($month) use ($data) {
            return (int)$data->get($month, 0); // 如果 $month 存在于 $ormResults 中，返回对应值；否则返回 0
        }, $date);
    }

    /**
     * @param $startTime
     * @param $endTime
     * @param $type
     * @return array
     */
    public function type2Orm($startTime, $endTime, $type): array
    {
        if ($type == 'year') {
            $groupBy = DB::raw('YEAR(gift_time)');
            $time = DB::raw('YEAR(gift_time) as time');

            $startDate = Carbon::parse($startTime )->startOfMonth();  // 2024-08-01 00:00:00
            $endDate = Carbon::parse($endTime)->endOfMonth();
        }elseif($type == 'month'){
            $groupBy = DB::raw('CONCAT(YEAR(gift_time), "-", LPAD(MONTH(gift_time), 2, "0"))');
            $time = DB::raw('CONCAT(YEAR(gift_time), "-", LPAD(MONTH(gift_time), 2, "0")) as time');

            $startDate = Carbon::parse($startTime )->startOfMonth();  // 2024-08-01 00:00:00
            $endDate = Carbon::parse($endTime)->endOfMonth();
        }else{
            $groupBy = DB::raw('DATE(gift_time)');
            $time = DB::raw('DATE(gift_time) as time');

            $startDate = Carbon::parse($startTime)->startOfDay();  // 2024-08-01 00:00:00
            $endDate = Carbon::parse($endTime)->endOfDay();
        }

        return [$groupBy,$time,$startDate,$endDate];
    }
    /**
     * @param $type
     * @param $startTime
     * @param $endTime
     * @return array
     */
    public function getDateList($type,$startTime,$endTime): array
    {
        if($type == 'year') {
            $startDate = Carbon::parse($startTime)->startOfMonth();
            $endDate = Carbon::parse($endTime)->endOfMonth();
            $startDateInt = Carbon::parse($startTime)->startOfMonth()->timestamp;
            $endDateInt = Carbon::parse($endTime)->endOfMonth()->timestamp;
        }elseif($type == 'month'){
            $startDate = Carbon::parse($startTime)->endOfDay();
            $endDate = Carbon::parse($endTime)->endOfDay();
            $startDateInt = Carbon::parse($startTime)->endOfDay()->timestamp;
            $endDateInt = Carbon::parse($endTime)->endOfDay()->timestamp;
        }else{
            $startDate = Carbon::parse($startTime);
            $endDate = Carbon::parse($endTime);
            $startDateInt = Carbon::parse($startTime)->timestamp;
            $endDateInt = Carbon::parse($endTime)->timestamp;
        }

        $date = [];
        // 生成月份数组
        $currentDate = $startDate->copy();
        while ($currentDate->lessThanOrEqualTo($endDate)) {
            if ($type == 'year') {
                $date[] = $currentDate->format('Y'); // 将月份以 "YYYY-MM" 格式添加到数组
                $currentDate->addYear();
            }elseif($type == 'month'){
                $date[] = $currentDate->format('Y-m'); // 将月份以 "YYYY-MM" 格式添加到数组
                $currentDate->addMonth();
            }else{
                $date[] = $currentDate->format('Y-m-d');
                $currentDate->addDay();
            }
        }
        return [$date,$startDate,$endDate];
    }
    /**
     * @param $type
     * @return array
     */
    public function getSelectListSallScores($request): array
    {
        $startTime = $request->input('start_time');
        $endTime = $request->input('end_time');
        $type = $request->input('type','month');
        return $this->getScores($startTime, $endTime, $type);
    }

    /**
     * @param $startTime
     * @param $endTime
     * @param $type
     * @param int $id
     * @return array
     */
    public function getScores($startTime, $endTime, $type, $id = 0): array
    {
        [$date, ,] = self::getDateList($type, $startTime, $endTime);
        //获取水机对应用户
        $orm = new UserScoreModel();
        if($id) {
            $apparatusList = UsersWithApparatuses::getInstance()->getUserApparatusByIds($id);
//            $orm = $orm->where('user_id', $id);
            $orm = $orm->whereIn('apparatus_id', array_keys($apparatusList));
        }
        [$groupBy,$time,$startDate,$endDate] = self::type2Orm($startTime,$endTime,$type);

//        $manage_list = UserScoreModel::getInstance()->getUserScoreStatistic(['type'=>ApparatusService::WATER_MANAGE,'user_id'=>$id,'start_time'=>$startDate,'end_time'=>$endDate,]);
        $buy_list = UserScoreModel::getInstance()->getUserScoreStatistic(['type'=>ApparatusService::WATER_BUY,'user_id'=>$id,'start_time'=>strtotime($startDate),'end_time'=>strtotime($endDate)]);

        exit(json_encode($buy_list));


        $orm = $orm->where('flag',0)
            ->whereBetween('gift_time', [strtotime($startDate), strtotime($endDate)])    // 月份结束时间
            ->select($time,DB::raw('SUM(score) as sum'))
            ->groupBy($groupBy)
            ->orderBy('time');
        //水机管理人
//        from_unixtime(gift_time,'%Y-%m-%d') as times


        $manageOrmClone = clone $orm;
        $manage = $manageOrmClone->where("type",ApparatusService::WATER_MANAGE)
            ->pluck('sum','time');
        $manage = array_map(function($month) use ($manage) {
            return (int)$manage->get($month, 0); // 如果 $month 存在于 $ormResults 中，返回对应值；否则返回 0
        }, $date);
        //水机购买人
        $buyOrmClone = clone $orm;
        $buy = $buyOrmClone->where("type",ApparatusService::WATER_BUY)
            ->pluck('sum','time');
        $buy = array_map(function($month) use ($buy) {
            return (int)$buy->get($month, 0); // 如果 $month 存在于 $ormResults 中，返回对应值；否则返回 0
        }, $date);
        return [
            'date' => $date,
            'series' => [
                [
                    'name' => '水机购买人积分',
                    'data' => $buy
                ],
                [
                    'name' => '水机管理人积分',
                    'data' => $manage
                ]
            ]
        ];
    }
    public function getSelectListsPropertyFee($request): array
    {
        $type = $request->input('type',0);

        $apparatusPropertyFeeOrm = new ApparatusPropertyFreeModel();
        if($type == 1){//3000以上
            //单位是分，所以是30000，下同
            $apparatusPropertyFeeOrm = $apparatusPropertyFeeOrm->having("total_price",'>=',300000);
        }else{//3000以下
            $apparatusPropertyFeeOrm = $apparatusPropertyFeeOrm->having("total_price",'<=',300000);
        }
        $list = $apparatusPropertyFeeOrm
            ->join('apparatuses', 'apparatus_property_fee.apparatus_id', '=', 'apparatuses.id')
            ->join('communities', 'apparatuses.community_id', '=', 'communities.id')
            ->select(
                'communities.title',  // 选择社区的 name
                DB::raw('SUM(grzt_apparatus_property_fee.price) as total_price')  // 计算 price 的合计
            )
            ->groupBy('communities.title')  // 按社区名称分组
            ->get();
        $date = [];
        $priceList = [];
        foreach ($list as $item) {
            $date[] = $item->name;
            $priceList[] = Arr::get($item,'total_price',0)/100;//单位：分;
        }
        return [
            'date' => $date,
            'series' => [
                [
                    'name' => '物业费',
                    'data' => $priceList
                ]
            ]
        ];
    }
}
